package com.songlanyun.modules.servicegoods.entity;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.type.TypeReference;
import com.songlanyun.common.drive.RootEntity;
import com.songlanyun.common.enums.GoodsConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.SpringContextUtils;
import com.songlanyun.common.utils.custom.ClassConvertUtils;
import com.songlanyun.common.validator.group.AddGroup;
import com.songlanyun.common.validator.group.UpdateGroup;
import com.songlanyun.modules.category.entity.SystemProductCategoryEntity;
import com.songlanyun.modules.category.service.SystemProductCategoryService;
import com.songlanyun.modules.goods.service.GoodsContentService;
import com.songlanyun.modules.group.model.vo.GoodsGroupSlim;
import com.songlanyun.modules.group.service.ProductGoodsGroupService;
import com.songlanyun.modules.inter.ISaleEntity;
import com.songlanyun.modules.servicegoods.service.ServiceGoodsClassifyService;
import com.songlanyun.modules.servicegoods.service.ServiceGoodsContentService;
import com.songlanyun.modules.servicegoods.service.ServiceGoodsGroupService;
import com.songlanyun.modules.servicegoods.service.ServiceItemService;
import com.songlanyun.modules.shop.entity.ShopEntity;
import com.songlanyun.modules.shop.service.ShopService;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.*;

/**
 * 服务商品
 *
 * @author lubo
 * @email sunlightcs@gmail.com
 * @date 2020-12-15 11:33:21
 */
@Data
@TableName("yxt_service_goods")
public class ServiceGoods extends RootEntity<Long, ServiceGoods> implements ISaleEntity, Serializable {
    private static final long serialVersionUID = 1L;

    {
        title = "";
        categoryId = 0L;
        salePrice = BigDecimal.ZERO;
        marketPrice = BigDecimal.ZERO;
        videoUrl = "";
		imagesValue = "";
		initSaleNum = 0;
        realSaleNum = 0;
		pv = 0;
		verifyStatus = GoodsConstant.VerifyStatus.YES;
		lastVerifyTime = new Date();
		added = true;
		sort = 0;
		hot = false;
		recommend =false;
		newGoods = false;
		code = "";
		validity = 0;
		advanceReservation = 0;
		welfareItems = new ArrayList<>();
		serviceCount = 1;
        verifyRemark="";
        deleted = 0;
    }

    /**
     * 服务商品id
     */
    @TableId
    private Long id;
    /**
     * 标题
     */
    @NotBlank(message = "标题名称不能为空")
    @Length(min = 1, max = 500, message = "商品标题名称长度在1-50个字")
    private String title;
    /**
     * 发布的商家店铺Id
     */
    @NotNull(message = "发布的商家店铺Id不能为空")
    private Long shopId;
    /**
     * 服务商品分类id
     */
    private Long categoryId;
    /**
     * 所属商品分类实体
     */
    @TableField(exist = false)
    @JsonIgnore
    private ServiceGoodsClassify category;

    /**
     * 加载所属分类
     *
     * @return
     */
    public ServiceGoodsClassify loadCategory() {
        if (category == null) {
            category = ((ServiceGoodsClassifyService) SpringContextUtils.getBean("serviceGoodsClassifyService")).getById(this.getCategoryId());
        }
        return category;
    }


    //所属分组================================================================================
    /**
     * 所属分组
     */
    @TableField(exist = false)
    private List<GoodsGroupSlim> groupList;

    /**
     * 加载所属商品分组（在需要后端需要加载的时候手动加载）
     *
     * @return
     */
    @JsonIgnore
    public List<GoodsGroupSlim> loadGroupList() {

        if (groupList == null) {
            ServiceGoodsGroupService service = ((ServiceGoodsGroupService) SpringContextUtils.getBean("serviceGoodsGroupService"));
            groupList = service.selectGoodsGroupRelation(getId());
        }
        return groupList;
    }


    /**
     * 售价
     */
    @DecimalMin(value = "0", message = "售价最小是0")
    @DecimalMax(value = "99999999", message = "售价最大是99999999")
    private BigDecimal salePrice;
    /**
     * 市场价
     */
    @DecimalMin(value = "0", message = "市场价最小是0")
    @DecimalMax(value = "99999999", message = "市场价最大是99999999")
    private BigDecimal marketPrice;
    /**
     * 主图视频
     */
    private String videoUrl;
    /**
     * 商品图片（5张）
     */
    @JsonIgnore
    private String imagesValue;

    @TableField(exist = false)
    private List<String> images;

    public List<String> getImages() {
        return images;
    }

    public void setImages(List<String> images) {
        this.images = images;
        if (images.isEmpty()) {
            throw new Error("商品图片不能为空");
        }
        this.imagesValue = JSONUtil.toJsonStr(this.images);
        setCover(images.get(0));
    }

    /**
     * 把字符串映射成对象（多图）
     */
    public void setImagesValue(String imagesValue) {
        this.imagesValue = imagesValue;
        if (StringUtils.isEmpty(this.imagesValue)) {
            setImages(new ArrayList<>());
        } else {
            try {
                setImages(ClassConvertUtils.stringToClassSnake(imagesValue, new TypeReference<List<String>>() {
                }));
            } catch (IOException e) {
                throw new RRException("商品图片无法转List");
            }

        }
    }

    /**
     * 封面图片
     */
    @NotBlank(message = "必须有封面图片")
    private String cover;

    //销量相关===================================================================================
    /**
     * 初始化销量
     */
    @Min(value = 0, message = "初始化销量最小是零")
    @Max(value = 99999999, message = "初始化销量最大是99999999", groups = {AddGroup.class, UpdateGroup.class})
    private Integer initSaleNum;
    /**
     * 真实销量
     */
    private Integer realSaleNum;
    /**
     * 输出销量
     */
    private Integer resultSaleNum;

    /**
     * 在实体添加，修改之前调用，在销量增减时也会调用一次
     */
    public void computeResultSaleNum() {
        this.resultSaleNum = this.initSaleNum + this.realSaleNum;
    }

    /**
     * 增加销量
     *
     * @param num
     */
    public void incSaleNum(int num) {
        this.realSaleNum += num;
        this.computeResultSaleNum();
    }

    /**
     * 减少销量
     *
     * @param num
     */
    public void decSaleNum(int num) {
        this.realSaleNum -= num;
        this.computeResultSaleNum();
    }

    /**
     * 所属商家
     */
    @TableField(exist = false)
    @JsonIgnore
    private ShopEntity shop;

    /**
     * 商家店铺
     *
     * @return
     */
    public ShopEntity loadShop() {
        if (shop == null) {
            shop = ((ShopService) SpringContextUtils.getBean("yxtShopService")).getById(this.getShopId());
        }
        return shop;
    }

    //销量相关结束===================================================================================


    /**
     * 加载商品详情
     */
    @TableField(exist = false)
    private String mobileDetail;

    /**
     * 加载商品详情
     *
     * @return
     */
    public String loadContent() {
        if (mobileDetail == null) {
            mobileDetail = ((ServiceGoodsContentService) SpringContextUtils.getBean("serviceGoodsContentService")).getByGoodsId(this.getId()).getMobileDetail();
        }
        return mobileDetail;
    }

    /**
     * 浏览量
     */
    private Integer pv;
    /**
     * 简介
     */
    private String remark;
    /**
     * 0待审核，1审核通过，2审核不通过
     */
    private GoodsConstant.VerifyStatus verifyStatus;

    /**
     * 审核文本
     */
    private String verifyRemark;
    /**
     * 是否上架
     */
    private Boolean added;
    /**
     * 顺序
     */
    private Integer sort;
    /**
     * 最后审核时间
     */
    private Date lastVerifyTime;
    /**
     * 软删除-1  ，0正常
     */
	@TableLogic
    private Integer deleted;

	@TableField(fill = FieldFill.INSERT)
	private Date createTime;

	@TableField(fill = FieldFill.INSERT_UPDATE)
	private Date updateTime;
    /**
     * 是否热销
     */
    private Boolean hot;
    /**
     * 是否是新品
     */
    private Boolean newGoods;
    /**
     * 是否推荐
     */
    private Boolean recommend;
    /**
     * 服务商品编码
     */
    private String code;
    /**
     * 消费有效期 过期后未消费自动退款
     */
    private Integer validity;
    /**
     * 提前预约天数
     */
    private Integer advanceReservation;
    /**
     * 免费福利项目(集合)
     */
    @TableField(exist=false)
    private List<String> welfareItems;

    private String welfareItemsValue;

    /**
     * 如果没有免费福利项目请传 []
     * @param welfareItems
     */
    public void setWelfareItems(List<String> welfareItems) {
        this.welfareItems = welfareItems;
        this.welfareItemsValue = JSONUtil.toJsonStr(this.welfareItems);
    }

    public  void  setWelfareItemsValue(String value)
    {
        this.welfareItemsValue = value;
        if (StringUtils.isEmpty(this.welfareItemsValue)) {
            setWelfareItems(new ArrayList<>());
        } else {
            try {
                setWelfareItems(ClassConvertUtils.stringToClassSnake(welfareItemsValue, new TypeReference<List<String>>() {
                }));
            } catch (IOException e) {
                throw new RRException("免费福利项目无法转List");
            }

        }
    }
    /**
     * 服务次数
     */
    @Range(min = 1,max = 999999,message = "服务次数值在1-999999次")
    private Integer serviceCount;



    //所属分组================================================================================
    /**
     * 服务项目
     */
    @TableField(exist = false)
    private List<ServiceItem> serviceItems;

    /**
     * 加载服务项目（在需要后端需要加载的时候手动加载）
     *
     * @return
     */
    public List<ServiceItem> loadServiceItems() {

        if (serviceItems == null) {
            ServiceItemService service = ((ServiceItemService) SpringContextUtils.getBean("serviceItemService"));
            serviceItems = service.loadServiceItem(getId());
        }
        return serviceItems;
    }




    @Override
    public Long getIdentity() {
        return getId();
    }

    @Override
    public boolean isVerify() {
        return GoodsConstant.VerifyStatus.YES.equals(this.getVerifyStatus());
    }
}
